package com.sinai.mshab.client.formatting;

import java.util.ArrayList;

import com.google.gwt.user.client.ui.Widget;

/**
 * This class manages all visibility logic, when things should be hidden or
 * shown.
 * 
 * @author serge
 * 
 */
public class VisibilityManager {

	// we need to remember all our rules.
	private ArrayList<VisiblityRule> rules = new ArrayList<VisiblityRule>();

	private static VisibilityManager visibility;

	private VisibilityManager() {

	}

	/**
	 * Returns an instance of the visibility manager
	 * 
	 * @return an instance of the visibility manager
	 */
	public static VisibilityManager getInstance() {
		if (visibility == null) {
			visibility = new VisibilityManager();
		}
		return visibility;
	}

	/**
	 * Adds a new rule, original widget will be shown if conditional widget is
	 * set.
	 * 
	 * @param original
	 *            the widget to hide or show
	 * @param conditional
	 *            the widget on whos value we decide to hide or show original
	 */
	public void addShowRule(Widget original, Widget conditional) {
		VisiblityRule rule = new VisiblityRule(original, conditional,
				VisiblityRule.SHOW);
		rules.add(rule);
		rule.execute();
	}

	/**
	 * Adds a new rule, original widget will be hidden if conditional widget is
	 * set.
	 * 
	 * @param original
	 *            the widget to hide or show
	 * @param conditional
	 *            the widget on whos value we decide to hide or show original
	 */
	public void addHideRule(Container original, Widget conditional) {
		VisiblityRule rule = new VisiblityRule(original, conditional,
				VisiblityRule.HIDE);
		rules.add(rule);
		rule.execute();
	}

	/**
	 * Adds a show/hide rule, the original widget will only be shown if the
	 * value of the conditional widget matches some regex
	 * 
	 * @param original the widget to hide or show
	 * @param conditional the trigger widget
	 * @param regex the regex that must be met for the widget to show
	 */
	public void addValueRule(Container original, Widget conditional,
			String regex) {
		VisiblityRule rule = new VisiblityRule(original, conditional, regex);
		rules.add(rule);
		rule.execute();
	}

	/**
	 * Executes all known visibility rules. Calling this method is useful after
	 * something like populate() due to the fact that there is no user
	 * interaction during the process, thus no onChange events are fired off to
	 * trigger rules.
	 */
	public void applyAllRules() {
		for (int i = 0; i < rules.size(); i++) {
			VisiblityRule rule = rules.get(i);
			rule.execute();
		}
	}
}
